今天要跟大家討論的是我們可能常用但卻不知道它叫 Callback function
。
Callback function
其實就是函式,差異只在 Callback function
是在指定時機才觸發的 function
,你可以在指定的時候,做完某件事情的時候才呼叫的函式,所以一句話來說就像是:「待會叫你」。
簡單舉例,下面是一般的函式
function callName(name) {
console.log(`hi!${name}`);
}
callName("Eazy"); //印出hi!Eazy
那如果我們今天會成這樣寫:
function callName() {
return;
}
function sayHello() {
console.log("hi");
}
callName(sayHello());
在開發的時候,常常會需要控制程式發生的順序,funcA 跑完之後再執行 funcB,再執行 funcD…等等,
Callback function
的用途就在於可以讓我們的程式在不論同步或是非同步執行的狀況下都還是可以依序執行函式。
綁定事件監聽器就是我們常用到的Callback function
。
btn.addEventListener("click", function () {
console.log(123);
});
有一個按鈕觸發點擊事件後在去呼叫後面的函式執行。
在需要延遲發生事件的時候也很常使用到。
btn.addEventListener("click", function () {
setTimeout(function () {
console.log(123);
}, 1000);
});
有一個按鈕觸發點擊事件後去呼叫裡面的setTimeout
執行,呼叫到setTimeout
後再執行裡面的函式。
講到 Callback function
的邏輯複雜、較難維護,很容易產生Callback Hell
。
Callback Hell
就是包了無限多層的 callback,做完第一件事之後做第二件事,再做第三件事...下去
看到這段程式碼你知道到底哪個函式執行完才會執行哪個函式嗎?
這時候Promise
的出現就是來解決這種狀況!
Promise
本身是用來改善 JavaScript 非同步的語法結構。
在過去的文章中有提到,JavaScript 是屬於同步的程式語言,因此一次僅能做一件事情,但遇到非同步的事件時,就會將非同步的事件移動到程式碼的最後方,等到所有的原始碼運行完以後才會執行非同步的事件。
console.log(123);
setTimeout(() => {
console.log(456);
}, 0);
console.log(789);
這段程式碼中有一個非同步的事件就算是我們把它的秒數調為0,還是會先執行console.log(123)
,在執行console.log(789)
,最後才會執行
setTimeout(() => {
console.log(456);
}, 0);
我們往往會希望結果是依照我們要的順序去運作,所以會用到Promise
。
那小夥伴一定會問要怎麼用Promise
?
const promise = new Promise(function(resolve, reject) {
resolve(value) //完成
reject(reason) //失敗
});
要提供一個函式 promise
功能,讓它回傳一個 promise
物件即可:
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
// resolve() or reject()
});
};
Promise
如果成功的話→(resolve),如果失敗的話...→(reject)。
pending
: 初始狀態,不是 fulfilled 或 rejected。fulfilled
: 表示操作成功地完成。rejected
: 表示操作失敗。
一般來說我們會用Promise
來獲取AJAX的資料。如果成功拿到資料就走.then(),失敗的話就.catch()。
透過這個方式我們可以擺脫Callback Hell
,只要一直.then()就可以了
因為如果第一個函式成功(resolve)了,會再進行第二個函式。第二個函式成功(resolve)了在執行第三個函式(resolve)。
重新認識 JavaScript: Day 26 同步與非同步
重新認識 JavaScript: Day 18 Callback Function 與 IIFE
[JavaScript] 一次搞懂同步與非同步的一切:待會叫你 — 回呼函式(Callback Function)